package com.gavin.plugin.database;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gavin.model.DataType;
import com.gavin.model.JObject;
import com.gavin.model.Model;
import com.gavin.model.Models;
import com.gavin.model.Request;
import com.gavin.model.Response;
import com.gavin.model.Result;
import com.gavin.model.RetCode;
import com.gavin.plugin.database.help.ConditionUtils;
import com.gavin.plugin.database.help.ShardingUtils;
import com.gavin.plugin.database.help.ValueUtils;
import com.gavin.plugin.database.optimize.TransLog;
import com.gavin.plugin.database.optimize.parse.ParsedSQL;
import com.gavin.plugin.service.ITransBus;
import com.gavin.schema.dataservice.BigTable;
import com.gavin.schema.dataservice.BlockType;
import com.gavin.schema.dataservice.BlockTypeItem;
import com.gavin.schema.dataservice.DataService;
import com.gavin.schema.dataservice.Delete;
import com.gavin.schema.dataservice.Else;
import com.gavin.schema.dataservice.For;
import com.gavin.schema.dataservice.HandleTrans;
import com.gavin.schema.dataservice.If;
import com.gavin.schema.dataservice.Insert;
import com.gavin.schema.dataservice.Log;
import com.gavin.schema.dataservice.OnError;
import com.gavin.schema.dataservice.OnException;
import com.gavin.schema.dataservice.SQLBlockType;
import com.gavin.schema.dataservice.SQLBlockTypeItem;
import com.gavin.schema.dataservice.SQLElse;
import com.gavin.schema.dataservice.SQLFor;
import com.gavin.schema.dataservice.SQLIf;
import com.gavin.schema.dataservice.SQLThen;
import com.gavin.schema.dataservice.SQLTrans;
import com.gavin.schema.dataservice.SQLTransChoiceItem;
import com.gavin.schema.dataservice.SelectConnection;
import com.gavin.schema.dataservice.SelectField;
import com.gavin.schema.dataservice.SelectRecord;
import com.gavin.schema.dataservice.SelectRecordSet;
import com.gavin.schema.dataservice.SetVar;
import com.gavin.schema.dataservice.Then;
import com.gavin.schema.dataservice.Update;

public class BigDataEngine implements IDataEngine {
	private static Logger logger = LoggerFactory.getLogger(BigDataEngine.class);

	private Random rand = new Random();
	private ITransBus transBus;
	
	public BigDataEngine() {
		this.transBus = null;
	}
	
	public void setTransBus(ITransBus transBus) {
		this.transBus = transBus;
	}

	private class DataAccess {
		DataEngine dataEngine;
		Connection conn;
		int nGroupIndex = -1;
		int nTableIndex = -1;
	}

	/**
	 * 执行事务
	 */
	@Override
	public Response execute(HashMap<String, DataEngineList> hmDataGroup, Map<String, SQLTrans> hmSQLTrans,Request request) {
		//设置分页信息
		Model trans=request.model();
		if(trans.exists("pageNumber") && trans.exists("pageSize")){
			Integer pageSize=trans.getInteger("pageSize");
			Integer pageNumber=trans.getInteger("pageNumber");
			if(pageSize==null){
				pageSize=10;
			}
			if(pageNumber==null){
				pageNumber=0;
			}
			Integer startIndex=pageSize*pageNumber;
			trans.set("startIndex", startIndex);
		}
		
		
		String transName = trans.getTransName();
		SQLTrans sqlTrans = hmSQLTrans.get(transName.toLowerCase());
		if (sqlTrans == null) {
			return Response.result(RetCode.REQUEST_FAIL, "trans "+transName+" not support!");
		}
		Response response=new Response();
		Result ret=this.executeTrans(hmDataGroup, sqlTrans, trans, response);
		if(ret==null){
			return Response.result(RetCode.REQUEST_FAIL,"请求失败");
		}
		response.setResult(ret.getCode());
		response.setMessage(ret.getText());
		return response;
	}

	//TODO
	@Override
	public Response execute(HashMap<String, DataEngineList> hmDataGroup, Map<String, SQLTrans> hmSQLTrans, IAtom iAtom) {
		String transName = iAtom.getRequest().getTransName();
		SQLTrans sqlTrans = hmSQLTrans.get(transName.toLowerCase());
		if (sqlTrans == null) {
			return Response.result(RetCode.REQUEST_FAIL, "trans "+transName+" not support!");
		}
		Response response=new Response();
		Result ret=this.executeTrans(hmDataGroup, sqlTrans, iAtom, response);
		if(ret==null){
			return Response.result(RetCode.REQUEST_FAIL,"请求失败");
		}
		response.setResult(ret.getCode());
		response.setMessage(ret.getText());
		return response;
	}

	private Result executeTrans(HashMap<String, DataEngineList> hmDataGroup, SQLTrans trans, Model modelRequest, Model modelResponse) {
		// 检查是否能处理该请求
		String transName = modelRequest.getTransName();
		if (trans == null) {// 不能处理该请求
			return null;
		}
		// 可以处理该请求
		DataService dataService = trans.getDataService();
		// 处理事务
		Result ret = new Result();
		HashMap<String, DataAccess> hmDataAccessUsed = new HashMap<String, DataAccess>();// key格式：bigtable.<name>或者group.<id>或者当前DataAccess使用的null
		hmDataAccessUsed.put(null, null);// 设置当前使用的dataaccess

		try {
			// 生成Block对象
			BlockType block = new BlockType();
			int nTransItemCount = trans.getSQLTransChoice(0).getSQLTransChoiceItemCount();
			for (int i = 0; i < nTransItemCount; i++) {
				SQLTransChoiceItem transItem = trans.getSQLTransChoice(0).getSQLTransChoiceItem(i);
				BlockTypeItem blockItem = null;
				if (transItem.getInsert() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setInsert(transItem.getInsert());
				} else if (transItem.getUpdate() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setUpdate(transItem.getUpdate());
				} else if (transItem.getDelete() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setDelete(transItem.getDelete());
				} else if (transItem.getSelectField() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setSelectField(transItem.getSelectField());
				} else if (transItem.getSelectRecord() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setSelectRecord(transItem.getSelectRecord());
				} else if (transItem.getSelectRecordSet() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setSelectRecordSet(transItem.getSelectRecordSet());
				} else if (transItem.getIf() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setIf(transItem.getIf());
				} else if (transItem.getFor() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setFor(transItem.getFor());
				} else if (transItem.getSetVar() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setSetVar(transItem.getSetVar());
				} else if (transItem.getSelectConnection() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setSelectConnection(transItem.getSelectConnection());
				} else if (transItem.getCommit() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setCommit(transItem.getCommit());
				} else if (transItem.getRollback() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setRollback(transItem.getRollback());
				} else if (transItem.getHandleTrans() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setHandleTrans(transItem.getHandleTrans());
				} else if (transItem.getLog() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setLog(transItem.getLog());
				}

				if (blockItem != null) {
					block.addBlockTypeItem(blockItem);
				}
			}

			// 处理事务
			int nResult = handleBlock(hmDataGroup, dataService, hmDataAccessUsed, trans, block, modelRequest, modelResponse, ret);
			if (nResult != 2) {// Break或自然执行完毕退出
				com.gavin.schema.dataservice.Return returnObject = trans.getReturn();
				ValueUtils.handleReturn(returnObject, modelRequest, modelResponse, ret);
			}

			if (ret.getCode() == 0) {
				if (trans.getTransFlag().getType() == 1) {//提交操作
					this.commitTrans(hmDataAccessUsed);
				}
			} else {
				if (trans.getTransFlag().getType() == 1) {//回滚操作
					this.rollbackTrans(hmDataAccessUsed);
				}
			}
		} catch (SQLException e) {
			this.rollbackTrans(hmDataAccessUsed);//回滚操作

			TransLog.onException(logger,"executeTrans Exception: " + transName, modelRequest, e);

			ret = null;

			OnException onException = trans.getOnException();
			int nErrorCount = onException.getOnErrorCount();
			for (int i = 0; i < nErrorCount; i++) {
				OnError onError = onException.getOnError(i);
				if (onError.getCode() == e.getErrorCode()) {
					int nReturnCode = ValueUtils.getIntegerValue(onError.getReturn().getCode(), modelRequest);
					ret = Result.valueOf(nReturnCode, onError.getReturn().getText(), onError.getReturn().getInfo());
					break;
				}
			}
			if (ret == null) {// 没有定义OnError
				String strText = onException.getReturn().getText();
				if ("OK".equalsIgnoreCase(strText)) {
					strText = "系统服务器故障";
				}
				int nReturnCode = ValueUtils.getIntegerValue(onException.getReturn().getCode(), modelRequest);
				ret = Result.valueOf(nReturnCode, strText, onException.getReturn().getInfo());
			}

			return ret;
		} catch (IOException e) {
			this.rollbackTrans(hmDataAccessUsed);

			TransLog.onException(logger,"executeTrans Exception: " + transName, modelRequest, e);

			OnException onException = trans.getOnException();
			int nReturnCode = ValueUtils.getIntegerValue(onException.getReturn().getCode(), modelRequest);
			ret = Result.valueOf(nReturnCode, onException.getReturn().getText(), onException.getReturn().getInfo());

			return ret;
		} catch (Exception e) {
			this.rollbackTrans(hmDataAccessUsed);

			TransLog.onException(logger,"executeTrans Exception: " + transName, modelRequest, e);

			OnException onException = trans.getOnException();
			int nReturnCode = ValueUtils.getIntegerValue(onException.getReturn().getCode(), modelRequest);
			ret = Result.valueOf(nReturnCode, onException.getReturn().getText(), onException.getReturn().getInfo());

			return ret;
		} finally {
			// 关闭连接
			Iterator<DataAccess> iterator = hmDataAccessUsed.values().iterator();
			while (iterator.hasNext()) {
				DataAccess dataAccess = (DataAccess) iterator.next();
				if (dataAccess == null) {
					continue;
				}

				try {
					dataAccess.conn.close();
				} catch (Exception e) {
				}
			}
		}
		return ret;
	}

	private Result executeTrans(HashMap<String, DataEngineList> hmDataGroup, SQLTrans trans, IAtom iAtom, Model modelResponse) {
		// 检查是否能处理该请求
		Model modelRequest=iAtom.getRequest().model();

		String transName = modelRequest.getTransName();
		if (trans == null) {// 不能处理该请求
			return null;
		}
		// 可以处理该请求
		DataService dataService = trans.getDataService();
		// 处理事务
		Result ret = new Result();
		HashMap<String, DataAccess> hmDataAccessUsed = new HashMap<String, DataAccess>();// key格式：bigtable.<name>或者group.<id>或者当前DataAccess使用的null
		hmDataAccessUsed.put(null, null);// 设置当前使用的dataaccess

		try {
			// 生成Block对象
			BlockType block = new BlockType();
			int nTransItemCount = trans.getSQLTransChoice(0).getSQLTransChoiceItemCount();
			for (int i = 0; i < nTransItemCount; i++) {
				SQLTransChoiceItem transItem = trans.getSQLTransChoice(0).getSQLTransChoiceItem(i);
				BlockTypeItem blockItem = null;
				if (transItem.getInsert() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setInsert(transItem.getInsert());
				} else if (transItem.getUpdate() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setUpdate(transItem.getUpdate());
				} else if (transItem.getDelete() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setDelete(transItem.getDelete());
				} else if (transItem.getSelectField() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setSelectField(transItem.getSelectField());
				} else if (transItem.getSelectRecord() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setSelectRecord(transItem.getSelectRecord());
				} else if (transItem.getSelectRecordSet() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setSelectRecordSet(transItem.getSelectRecordSet());
				} else if (transItem.getIf() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setIf(transItem.getIf());
				} else if (transItem.getFor() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setFor(transItem.getFor());
				} else if (transItem.getSetVar() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setSetVar(transItem.getSetVar());
				} else if (transItem.getSelectConnection() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setSelectConnection(transItem.getSelectConnection());
				} else if (transItem.getCommit() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setCommit(transItem.getCommit());
				} else if (transItem.getRollback() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setRollback(transItem.getRollback());
				} else if (transItem.getHandleTrans() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setHandleTrans(transItem.getHandleTrans());
				} else if (transItem.getLog() != null) {
					blockItem = new BlockTypeItem();
					blockItem.setLog(transItem.getLog());
				}

				if (blockItem != null) {
					block.addBlockTypeItem(blockItem);
				}
			}

			// 处理事务
			int nResult = handleBlock(hmDataGroup, dataService, hmDataAccessUsed, trans, block, modelRequest, modelResponse, ret);
			if (nResult != 2) {// Break或自然执行完毕退出
				com.gavin.schema.dataservice.Return returnObject = trans.getReturn();
				ValueUtils.handleReturn(returnObject, modelRequest, modelResponse, ret);
			}

			if (ret.getCode() == 0) {
				if (trans.getTransFlag().getType() == 1) {//提交操作
					boolean flag=false;
					try {
						flag=iAtom.excueter();
						if(flag){
							ret = Result.valueOf(ret.getCode(), ret.getText(), ret.getInfo());
							this.commitTrans(hmDataAccessUsed);
						}else{
							ret = Result.valueOf(-1, "外部执行失败", "外部执行失败");
							this.rollbackTrans(hmDataAccessUsed);
						}
					}catch (Exception e){
						ret = Result.valueOf(-1, "外部事物执行异常", "");
						this.rollbackTrans(hmDataAccessUsed);
					}
				}
			} else {
				if (trans.getTransFlag().getType() == 1) {//回滚操作
					this.rollbackTrans(hmDataAccessUsed);
				}
			}
		} catch (SQLException e) {
			this.rollbackTrans(hmDataAccessUsed);//回滚操作

			TransLog.onException(logger,"executeTrans Exception: " + transName, modelRequest, e);

			ret = null;

			OnException onException = trans.getOnException();
			int nErrorCount = onException.getOnErrorCount();
			for (int i = 0; i < nErrorCount; i++) {
				OnError onError = onException.getOnError(i);
				if (onError.getCode() == e.getErrorCode()) {
					int nReturnCode = ValueUtils.getIntegerValue(onError.getReturn().getCode(), modelRequest);
					ret = Result.valueOf(nReturnCode, onError.getReturn().getText(), onError.getReturn().getInfo());
					break;
				}
			}
			if (ret == null) {// 没有定义OnError
				String strText = onException.getReturn().getText();
				if ("OK".equalsIgnoreCase(strText)) {
					strText = "系统服务器故障";
				}
				int nReturnCode = ValueUtils.getIntegerValue(onException.getReturn().getCode(), modelRequest);
				ret = Result.valueOf(nReturnCode, strText, onException.getReturn().getInfo());
			}

			return ret;
		} catch (IOException e) {
			this.rollbackTrans(hmDataAccessUsed);

			TransLog.onException(logger,"executeTrans Exception: " + transName, modelRequest, e);

			OnException onException = trans.getOnException();
			int nReturnCode = ValueUtils.getIntegerValue(onException.getReturn().getCode(), modelRequest);
			ret = Result.valueOf(nReturnCode, onException.getReturn().getText(), onException.getReturn().getInfo());

			return ret;
		} catch (Exception e) {
			this.rollbackTrans(hmDataAccessUsed);

			TransLog.onException(logger,"executeTrans Exception: " + transName, modelRequest, e);

			OnException onException = trans.getOnException();
			int nReturnCode = ValueUtils.getIntegerValue(onException.getReturn().getCode(), modelRequest);
			ret = Result.valueOf(nReturnCode, onException.getReturn().getText(), onException.getReturn().getInfo());

			return ret;
		} finally {
			// 关闭连接
			Iterator<DataAccess> iterator = hmDataAccessUsed.values().iterator();
			while (iterator.hasNext()) {
				DataAccess dataAccess = (DataAccess) iterator.next();
				if (dataAccess == null) {
					continue;
				}

				try {
					dataAccess.conn.close();
				} catch (Exception e) {
				}
			}
		}
		return ret;
	}


	/**
	 * 处理SQL语句中的If语句
	 * 
	 * @param sqlIf
	 * @param modelRequest
	 * @return 0-自然执行完毕，1-碰到Break退出，2-碰到Return退出
	 * @throws Exception
	 */
	private int handleSQLIf(SQLIf sqlIf, Model modelRequest, StringBuilder strbSQL) {
		// 检查执行条件
		boolean bCondition = ConditionUtils.checkCondition(sqlIf, modelRequest);
		if (bCondition == true) {// Handle Then
			SQLThen sqlThen = sqlIf.getSQLThen();
			return handleSQLBlock(sqlThen, modelRequest, strbSQL);
		} else {// handle Else
			SQLElse sqlElse = sqlIf.getSQLElse();
			if (sqlElse == null) {// 自然完成
				return 0;
			}
			return handleSQLBlock(sqlElse, modelRequest, strbSQL);
		}
	}

	/**
	 * 处理SQL语句中的For语句
	 * 
	 * @param sqlFor
	 * @param modelRequest
	 * @param strbSQL
	 * @return 0-自然执行完毕，1-碰到Break退出，2-碰到Return退出
	 * @throws Exception
	 */
	private int handleSQLFor(SQLFor sqlFor, Model modelRequest, StringBuilder strbSQL) {
		// 获取循环数据
		int nFromIndex = ValueUtils.getIntegerValue(sqlFor.getFromIndex(), modelRequest);
		int nCount = ValueUtils.getIntegerValue(sqlFor.getCount(), modelRequest);
		String strIndexId = sqlFor.getIndexId();
		strIndexId = strIndexId.substring(1, strIndexId.length() - 1);

		// 执行循环
		for (int i = nFromIndex; i < nFromIndex + nCount; i++) {
			// 设置IndexId
			modelRequest.set(strIndexId, i);

			// 执行Block
			int nResult = handleSQLBlock(sqlFor, modelRequest, strbSQL);
			if (nResult == 0) {// 自然执行完毕
				continue;
			} else if (nResult == 1) {// 碰到Break
				break;
			} else {// 碰到Return
				return nResult;
			}
		}

		return 0;
	}

	/**
	 * 处理SQLBlock对象，得到输出的SQL语句
	 * 
	 * @param sqlBlock
	 * @return 0-自然执行完毕，1-碰到Break退出，2-碰到Return退出
	 */
	private int handleSQLBlock(SQLBlockType sqlBlock, Model modelRequest, StringBuilder strbSQL) {
		// 依次处理各个Item
		int nItemCount = sqlBlock.getSQLBlockTypeItemCount();
		for (int i = 0; i < nItemCount; i++) {
			// 处理当前的Item
			SQLBlockTypeItem item = sqlBlock.getSQLBlockTypeItem(i);
			if (item.getOutputSQL() != null) {// OutputSQL,直接输出源文本
				strbSQL.append(item.getOutputSQL());
			} else if (item.getOutputField() != null) {// OutputField，输出文本代表的字段值
				String strOutputFieldId = item.getOutputField();
				strOutputFieldId = strOutputFieldId.substring(1, strOutputFieldId.length() - 1);
				strbSQL.append(modelRequest.getString(strOutputFieldId));
			} else if (item.getSQLIf() != null) {// SQLIf
				int nResult = handleSQLIf(item.getSQLIf(), modelRequest, strbSQL);
				if (nResult == 0) {// 自然执行完毕
					continue;
				} else {// 碰到Break或Return
					return nResult;
				}
			} else if (item.getSQLFor() != null) {// SQLFor
				int nResult = handleSQLFor(item.getSQLFor(), modelRequest, strbSQL);
				if (nResult == 0) {// 自然执行完毕
					continue;
				} else {// 碰到Break或Return
					return nResult;
				}
			} else {
				continue;
			}
		}

		// 自然执行完毕
		return 0;
	}

	/**
	 * 处理If语句
	 * 
	 * @param ifItem
	 * @param modelRequest
	 * @return 0-自然执行完毕，1-碰到Break退出，2-碰到Return退出
	 * @throws Exception
	 */
	private int handleIf(HashMap<String, DataEngineList> hmDataGroup, DataService dataService,
			HashMap<String, DataAccess> hmDataAccess, SQLTrans trans, If ifItem, Model modelRequest,
			Model modelResponse, Result ret) throws SQLException, IOException {
		// 检查执行条件
		boolean bCondition = ConditionUtils.checkCondition(ifItem, modelRequest);
		if (bCondition == true) {// Handle Then
			Then thenItem = ifItem.getThen();
			return handleBlock(hmDataGroup, dataService, hmDataAccess, trans, thenItem, modelRequest, modelResponse, ret);
		} else {// handle Else
			Else elseItem = ifItem.getElse();
			if (elseItem == null) {// 没有else模块，当作自然执行完毕处理???
				return 0;
			}
			return handleBlock(hmDataGroup, dataService, hmDataAccess, trans, elseItem, modelRequest, modelResponse, ret);
		}
	}

	/**
	 * 处理For语句
	 * @param modelRequest
	 * @return 0-自然执行完毕，1-碰到Break退出，2-碰到Return退出
	 * @throws Exception
	 */
	private int handleFor(HashMap<String, DataEngineList> hmDataGroup, DataService dataService,
			HashMap<String, DataAccess> hmDataAccess, SQLTrans trans, For forItem, Model modelRequest,
			Model modelResponse, Result ret) throws SQLException, IOException {
		// 获取循环数据
		int nFromIndex = ValueUtils.getIntegerValue(forItem.getFromIndex(), modelRequest);
		int nCount = ValueUtils.getIntegerValue(forItem.getCount(), modelRequest);
		String strIndexId = forItem.getIndexId();
		strIndexId = strIndexId.substring(1, strIndexId.length() - 1);

		// 执行循环
		for (int i = nFromIndex; i < nFromIndex + nCount; i++) {
			// 设置IndexId
			modelRequest.set(strIndexId, i);

			// 执行Block
			int nResult = handleBlock(hmDataGroup, dataService, hmDataAccess, trans, forItem, modelRequest, modelResponse,ret);
			if (nResult == 0) {// 自然执行完毕
				continue;
			} else if (nResult == 1) {// 碰到Break
				break;
			} else {// 碰到Return
				return nResult;
			}
		}

		return 0;
	}



	private void handleHandleTrans(HashMap<String, DataEngineList> hmDataGroup, DataService dataService,
			HashMap<String, DataAccess> hmDataAccess, SQLTrans trans, HandleTrans htItem, Model modelRequest,
			Model modelResponse, Result ret) throws SQLException, IOException {
		Request request = ValueUtils.newRequest(htItem, modelRequest, modelResponse);
		Response retTrans = this.transBus.execute(request);
		if (retTrans != null) {
			modelRequest.set(ValueUtils.getFieldId(htItem.getResponseId()), retTrans);
			Model modelReturn = new Model();
			modelReturn.set("nCode", retTrans.getResult());
			modelReturn.set("strText", retTrans.getString("text"));
			modelReturn.set("strInfo", retTrans.getString("info"));
			modelRequest.set(ValueUtils.getFieldId(htItem.getReturnId()), modelReturn);
		}
	}

	private BigTable getBigTable(String tableName) {
		return this.transBus.getTableRule(tableName);
	}

	private DataAccess createDataAccess(HashMap<String, DataEngineList> hmDataGroup, String strDataGroupId) throws SQLException {
		// 没有可重用的DataAccess
		DataEngineList clDataEngine = hmDataGroup.get(strDataGroupId);
		if (clDataEngine == null) {// DataGroupId错误
			throw new RuntimeException("Invalid data group id: " + strDataGroupId);
		}

		// 创建Connection
		DataEngine dataEngine = clDataEngine.get();
		Connection conn = dataEngine.getConnection();
		if (conn == null) {
			throw new RuntimeException("Get database connection failed: " + strDataGroupId);
		}
		DataAccess da = new DataAccess();
		da.dataEngine = dataEngine;
		da.conn = conn;

		return da;
	}

//	private int selectTable(Model modelRequest, String strBigTableName, String strIdParaName) throws SQLException {
//		BigTable bigTable = this.getBigTable(strBigTableName);
//		if (bigTable == null) {
//			throw new SQLException("Dest-table not found: " + strBigTableName);
//		}
//
//		long lId = ValueUtils.getKeyIdValue(strIdParaName, modelRequest, bigTable.getHashedIdCount());
//
//		return (int) ((lId / bigTable.getGroupTableCapacity()));
//	}

//	private int selectDatabase(Model modelRequest, String strBigTableName, String strIdParaName) throws SQLException {
//		BigTable bigTable = this.getBigTable(strBigTableName);
//		if (bigTable == null) {
//			throw new SQLException("Dest-table not found: " + strBigTableName);
//		}
//
//		long lId = ValueUtils.getKeyIdValue(strIdParaName, modelRequest, bigTable.getHashedIdCount());
//
//		return (int) ((lId / bigTable.getGroupTableCapacity()) / bigTable.getGroupTableCount());
//	}

	private void selectTable(DataAccess dataAccess, BigTable bigTable, String strIdMath, boolean bRandSelect,
			Model modelRequest) {
		if (strIdMath == null) {// 没有提供 IdFieldId
			if (bRandSelect == false) {// 不可以随机获取
				return;
			}
			// 可以随机，随机分配一个Table
			dataAccess.nTableIndex = rand.nextInt(bigTable.getGroupTableCount());
			return;
		}

		// 提供了Id
		long lId = ShardingUtils.getKeyIdValue(strIdMath, modelRequest, bigTable.getHashedIdCount());
		dataAccess.nTableIndex = (int) ((lId / bigTable.getGroupTableCapacity()));
	}

	/**
	 * 根据BigTableName和Id选择连接输出
	 */
	private DataAccess selectConnection(HashMap<String, DataEngineList> hmDataGroup, DataService dataService,
			String strDefaultDataGroupId, String strBigTableName, String strIdFieldId, boolean bRandSelect,
			Model modelRequest, HashMap<String, DataAccess> hmDataAccessUsed, SQLTrans trans) throws SQLException {
		DataAccess da = null;

		try {
			if (strBigTableName == null || strBigTableName.length() == 0) {// 没有BigTable
				da = hmDataAccessUsed.get("group." + strDefaultDataGroupId);
				if (da != null) {// 有可重用的DataAccess
					hmDataAccessUsed.put(null, da);
					return da;
				}
				// 没有可重用的DataAccess
				da = this.createDataAccess(hmDataGroup, strDefaultDataGroupId);

				hmDataAccessUsed.put("group." + strDefaultDataGroupId, da);
				hmDataAccessUsed.put(null, da);

				return da;
			}

//			if (dataService.hasBigTable() == false) {// BigTable没有配置
//				return null;
//			}

			BigTable bigTable = getBigTable(strBigTableName);
			if (bigTable == null) {// 该BigTable没有配置
				return null;
			}

			// 找到BigTable
			if (strIdFieldId == null || strIdFieldId.length() == 0) {// 没有提供
																		// IdFieldId，要么使用以前的连接，要么重新创建连接
																		// 尝试重用已有的DataAccess
				da = hmDataAccessUsed.get("table." + strBigTableName);
				if (da != null) {// 有可重用的DataAccess
					hmDataAccessUsed.put(null, da);
					return da;
				}
				if (bRandSelect == false) {// 不可以随机获取，只能使用以前的连接
					return null;
				}

				// 随机获取连接，随机分配一个Table
				int nGroupIndex = rand.nextInt(bigTable.getGroupCount());
				da = this.createDataAccess(hmDataGroup, bigTable.getGroupId() + nGroupIndex);
				da.nGroupIndex = nGroupIndex;
				String strConnectionId = bigTable.getGroupId() + nGroupIndex;

				hmDataAccessUsed.put("group." + strConnectionId, da);
				hmDataAccessUsed.put("table." + strBigTableName, da);
				hmDataAccessUsed.put(null, da);
				return da;
			}

			if(!modelRequest.exists(strIdFieldId)){
				throw new RuntimeException("invalid param: " + strIdFieldId);
			}
			// 提供了IdFieldId
			long lId = ShardingUtils.getKeyIdValue(strIdFieldId, modelRequest, bigTable.getHashedIdCount());
			int nGroupIndex = (int) (lId / bigTable.getGroupTableCapacity()) / bigTable.getGroupTableCount();
			String strConnectionId = bigTable.getGroupId() + nGroupIndex;

			// 首先尝试重用已有的DataAccess
			da = hmDataAccessUsed.get("group." + strConnectionId);
			if (da != null) {// 有可重用的DataAccess
				hmDataAccessUsed.put(null, da);
				hmDataAccessUsed.put("table." + strBigTableName, da);// 2016.10.10新增
				return da;
			}

			// 没有可重用的DataAccess，重新获取连接
			da = this.createDataAccess(hmDataGroup, strConnectionId);
			da.nGroupIndex = nGroupIndex;

			hmDataAccessUsed.put("group." + strConnectionId, da);
			hmDataAccessUsed.put("table." + strBigTableName, da);
			hmDataAccessUsed.put(null, da);
			return da;
		} finally {
			if (da != null) {
				if (trans.getTransFlag().getType() == 1) {
					da.conn.setAutoCommit(false);
				}
			}
		}
	}





	/**
	 * 执行insert语句
	 * 
	 * @param hmDataGroup
	 * @param strSQL
	 * @param modelRequest
	 * @return
	 * @throws Exception
	 */
	private int executeInsert(HashMap<String, DataEngineList> hmDataGroup, DataService dataService,
			HashMap<String, DataAccess> hmDataAccessUsed, SQLTrans trans, String strSQL, Model modelRequest)
			throws SQLException, IOException {
		// 分析原先的SQL语句
//		String strBigTableGroupId = trans.getBigTableGroupId();
//		BigTable[] bts = dataService.getBigTableArray(strBigTableGroupId);

		ParsedSQL parsedSQL = null;
		try {
			parsedSQL = ParsedSQL.parseSourceSQL(strSQL, modelRequest,transBus);
		} catch (Exception e) {
			throw new SQLException("Parse SQL failed: " + strSQL, e);
		}

		String strDefaultDataGroupId = trans.getDataGroupId();
		if (parsedSQL.getDataGroupId() != null) {
			strDefaultDataGroupId = parsedSQL.getDataGroupId();
		}
		DataAccess dataAccess = null;
		if (parsedSQL.getTableName() == null) {// 没有BigTable
												// 获取连接
			dataAccess = this.selectConnection(hmDataGroup, dataService, strDefaultDataGroupId, null, null, false,
					modelRequest, hmDataAccessUsed, trans);
			if (dataAccess == null) {
				throw new SQLException("Invalid datagroup id: " + strDefaultDataGroupId + ", " + strSQL);
			}

			// 执行数据库操作
			dataAccess.dataEngine.executeUpdate(dataAccess.conn, parsedSQL.getSQL(), modelRequest);

			return 0;
		}

		// 有BigTable，尝试定位目标表
		BigTable bigTable = this.getBigTable(parsedSQL.getTableName());
		if (bigTable == null) {
			throw new SQLException("Dest-table not found: " + strSQL);
		}
		// 获取连接
		dataAccess = this.selectConnection(hmDataGroup, dataService, strDefaultDataGroupId, parsedSQL.getTableName(),
				parsedSQL.getIdMath(), true, modelRequest, hmDataAccessUsed, trans);
		if (dataAccess == null) {
			throw new SQLException("Cannot get connection: " + strSQL + "\r\n" + modelRequest.toXML());
		}
		this.selectTable(dataAccess, bigTable, parsedSQL.getIdMath(), true, modelRequest);

		// 修改SQL语句中的表名
		strSQL = parsedSQL.getSQL().toString().replaceAll("\\{T:" + parsedSQL.getTableName() + "\\}",
				parsedSQL.getTableName() + dataAccess.nTableIndex);

		// 执行数据库操作
		dataAccess.dataEngine.executeUpdate(dataAccess.conn, strSQL, modelRequest);

		return 0;
	}

	/**
	 * 通过一个传入的数据库连接查询并输出第一条记录
	 *
	 * @param strSQL
	 * @param modelRequest
	 * @param modelResponse
	 * @return
	 * @throws Exception
	 */
	private int executeQueryRecord(HashMap<String, DataEngineList> hmDataGroup, DataService dataService, HashMap<String, DataAccess> hmDataAccessUsed, SQLTrans trans, String strSQL, Model modelRequest,Model modelResponse, String strDecryptFieldNames) throws SQLException, IOException {
		// 分析原先的SQL语句
//		String strBigTableGroupId = trans.getBigTableGroupId();
//		BigTable[] bts = dataService.getBigTableArray(strBigTableGroupId);
		ParsedSQL parsedSQL = null;
		try {
			parsedSQL = ParsedSQL.parseSourceSQL( strSQL, modelRequest,transBus);
		} catch (Exception e) {
			throw new SQLException("Parse SQL failed: " + strSQL, e);
		}

		DataAccess dataAccess = null;
		String strDefaultDataGroupId = trans.getDataGroupId();
		if (parsedSQL.getDataGroupId() != null) {
			strDefaultDataGroupId = parsedSQL.getDataGroupId();
		}
		if (parsedSQL.getTableName() == null) {// 没有BigTable
												// 获取连接
			dataAccess = this.selectConnection(hmDataGroup, dataService, strDefaultDataGroupId, null, null, false, modelRequest, hmDataAccessUsed, trans);
			if (dataAccess == null) {
				throw new SQLException("Invalid datagroup id: " + strDefaultDataGroupId + ", " + strSQL);
			}

			// 执行数据库操作
			HashSet<String> hsDecryptFieldNames = ValueUtils.getDecryptFieldNames(strDecryptFieldNames);
			return dataAccess.dataEngine.executeQueryRecord(dataAccess.conn, parsedSQL.getSQL(), modelRequest, modelResponse, hsDecryptFieldNames);
		}

		// 有BigTable，尝试定位目标表
		BigTable bigTable = this.getBigTable(parsedSQL.getTableName());
		if (bigTable == null) {
			throw new SQLException("Dest-table not found: " + strSQL);
		}
		// 获取连接
		dataAccess = this.selectConnection(hmDataGroup, dataService, strDefaultDataGroupId, parsedSQL.getTableName(), parsedSQL.getIdMath(), false, modelRequest, hmDataAccessUsed, trans);
		if (dataAccess == null) {// 没有拿到连接
			throw new SQLException("Cannot get connection: " + strSQL + "\r\n" + modelRequest.toXML());
		}
		// 拿到了连接
		this.selectTable(dataAccess, bigTable, parsedSQL.getIdMath(), false, modelRequest);

		// 修改SQL语句中的表名
		strSQL = parsedSQL.getSQL().toString().replaceAll("\\{T:" + parsedSQL.getTableName() + "\\}", parsedSQL.getTableName() + dataAccess.nTableIndex);

		// 执行数据库操作
		HashSet<String> hsDecryptFieldNames = ValueUtils.getDecryptFieldNames(strDecryptFieldNames);
		return dataAccess.dataEngine.executeQueryRecord(dataAccess.conn, strSQL, modelRequest, modelResponse, hsDecryptFieldNames);
	}

	/**
	 * 执行查询操作，输出多条记录
	 *
	 * @param strSQL
	 * @param modelRequest
	 * @return
	 * @throws Exception
	 */
	private int executeQueryRecordSet(HashMap<String, DataEngineList> hmDataGroup, DataService dataService,
			HashMap<String, DataAccess> hmDataAccessUsed, SQLTrans trans, String strSQL, Model modelRequest,
			Models modelsOutput, String strDecryptFieldNames) throws SQLException, IOException {
		// 分析原先的SQL语句
//		String strBigTableGroupId = trans.getBigTableGroupId();
//		BigTable[] bts = dataService.getBigTableArray(strBigTableGroupId);

		System.out.println("原始："+strSQL);

		ParsedSQL parsedSQL = null;
		try {
			parsedSQL = ParsedSQL.parseSourceSQL(strSQL, modelRequest,transBus);
		} catch (Exception e) {
			throw new SQLException("Parse SQL failed: " + strSQL, e);
		}
		System.out.println(parsedSQL);

		HashSet<String> hsDecryptFieldNames = ValueUtils.getDecryptFieldNames(strDecryptFieldNames);

		DataAccess dataAccess = null;
		String strDefaultDataGroupId = trans.getDataGroupId();
		if (parsedSQL.getDataGroupId() != null) {
			strDefaultDataGroupId = parsedSQL.getDataGroupId();
		}
		if (parsedSQL.getTableName() == null) {// 没有BigTable
			// 获取连接
			dataAccess = this.selectConnection(hmDataGroup, dataService, strDefaultDataGroupId, null, null, false, modelRequest, hmDataAccessUsed, trans);
			if (dataAccess == null) {
				throw new SQLException("Invalid datagroup id: " + strDefaultDataGroupId + ", " + strSQL);
			}

			// 执行数据库操作
			return dataAccess.dataEngine.executeQueryRecordSet(dataAccess.conn, parsedSQL.getSQL(), modelRequest,
					hsDecryptFieldNames, modelsOutput);
		}

		// 有BigTable，尝试定位目标表
		BigTable bigTable = this.getBigTable(parsedSQL.getTableName());
		if (bigTable == null) {
			throw new SQLException("Dest-table not found: " + strSQL);
		}
		// 获取连接
		dataAccess = this.selectConnection(hmDataGroup, dataService, strDefaultDataGroupId, parsedSQL.getTableName(),
				parsedSQL.getIdMath(), false, modelRequest, hmDataAccessUsed, trans);
		if (dataAccess == null) {// 没有拿到连接
			throw new SQLException("Cannot get connection: " + strSQL + "\r\n" + modelRequest.toXML());
		}
		// 拿到了连接
		this.selectTable(dataAccess, bigTable, parsedSQL.getIdMath(), false, modelRequest);

		// 修改SQL语句中的表名
		strSQL = parsedSQL.getSQL().toString().replaceAll("\\{T:" + parsedSQL.getTableName() + "\\}",
				parsedSQL.getTableName() + dataAccess.nTableIndex);

		// 执行数据库操作
		return dataAccess.dataEngine.executeQueryRecordSet(dataAccess.conn, strSQL, modelRequest, hsDecryptFieldNames,
				modelsOutput);
	}

	/**
	 * 查询第一条记录的第一个字段
	 *
	 * @param strSQL
	 * @param modelRequest
	 * @return
	 * @throws Exception
	 */
	private JObject executeQueryFieldExt(HashMap<String, DataEngineList> hmDataGroup, DataService dataService,
			HashMap<String, DataAccess> hmDataAccessUsed, SQLTrans trans, String strSQL, Model modelRequest,
			String strDecryptFieldNames) throws SQLException, IOException {
		// 分析原先的SQL语句
//		String strBigTableGroupId = trans.getBigTableGroupId();
//		BigTable[] bts = dataService.getBigTableArray(strBigTableGroupId);
//		HashMap<String, BigTable> hmBigTable=dataService.getTableRule();
		ParsedSQL parsedSQL = null;
		try {
			parsedSQL = ParsedSQL.parseSourceSQL(strSQL, modelRequest,transBus);
		} catch (Exception e) {
			throw new SQLException("Parse SQL failed: " + strSQL, e);
		}

		DataAccess dataAccess = null;
		String strDefaultDataGroupId = trans.getDataGroupId();
		if (parsedSQL.getDataGroupId() != null) {
			strDefaultDataGroupId = parsedSQL.getDataGroupId();
		}
		if (parsedSQL.getTableName() == null) {// 没有BigTable
												// 获取连接
			dataAccess = this.selectConnection(hmDataGroup, dataService, strDefaultDataGroupId, null, null, false,modelRequest, hmDataAccessUsed, trans);
			if (dataAccess == null) {
				throw new SQLException("Invalid datagroup id: " + strDefaultDataGroupId + ", " + strSQL);
			}

			// 执行数据库操作
			HashSet<String> hsDecryptFieldNames = ValueUtils.getDecryptFieldNames(strDecryptFieldNames);
			return dataAccess.dataEngine.executeQueryFieldExt(dataAccess.conn, parsedSQL.getSQL(), modelRequest,
					hsDecryptFieldNames);
		}

		// 有BigTable，尝试定位目标表
		BigTable bigTable = this.getBigTable(parsedSQL.getTableName());
		if (bigTable == null) {
			throw new SQLException("Dest-table not found: " + strSQL);
		}
		// 获取连接
		dataAccess = this.selectConnection(hmDataGroup, dataService, strDefaultDataGroupId, parsedSQL.getTableName(),
				parsedSQL.getIdMath(), true, modelRequest, hmDataAccessUsed, trans);
		if (dataAccess == null) {// 没有拿到连接
			throw new SQLException("Cannot get connection: " + strSQL + "\r\n" + modelRequest.toXML());
		}

		// 拿到了连接
		this.selectTable(dataAccess, bigTable, parsedSQL.getIdMath(), true, modelRequest);

		// 修改SQL语句中的表名
		strSQL = parsedSQL.getSQL().toString().replaceAll("\\{T:" + parsedSQL.getTableName() + "\\}",
				parsedSQL.getTableName() + dataAccess.nTableIndex);

		// 执行数据库操作
		HashSet<String> hsDecryptFieldNames = ValueUtils.getDecryptFieldNames(strDecryptFieldNames);
		return dataAccess.dataEngine.executeQueryFieldExt(dataAccess.conn, strSQL, modelRequest, hsDecryptFieldNames);
	}

	/**
	 * 更新数据库记录或删除数据库记录
	 *
	 * @param strSQL
	 * @param modelRequest
	 * @return
	 * @throws Exception
	 */
	private int executeUpdate(HashMap<String, DataEngineList> hmDataGroup, DataService dataService,
			HashMap<String, DataAccess> hmDataAccessUsed, SQLTrans trans, String strSQL, Model modelRequest)
			throws SQLException, IOException {
		// 分析原先的SQL语句
//		String strBigTableGroupId = trans.getBigTableGroupId();
//		BigTable[] bts = dataService.getBigTableArray(strBigTableGroupId);

		ParsedSQL parsedSQL = null;
		try {
			parsedSQL = ParsedSQL.parseSourceSQL(strSQL, modelRequest,transBus);
		} catch (Exception e) {
			throw new SQLException("Parse SQL failed: " + strSQL, e);
		}

		DataAccess dataAccess = null;
		String strDefaultDataGroupId = trans.getDataGroupId();
		if (parsedSQL.getDataGroupId() != null) {
			strDefaultDataGroupId = parsedSQL.getDataGroupId();
		}
		if (parsedSQL.getTableName() == null) {// 没有BigTable
												// 获取连接
			dataAccess = this.selectConnection(hmDataGroup, dataService, strDefaultDataGroupId, null, null, false,
					modelRequest, hmDataAccessUsed, trans);
			if (dataAccess == null) {
				throw new SQLException("Invalid datagroup id: " + strDefaultDataGroupId + ", " + strSQL);
			}

			// 执行数据库操作
			return dataAccess.dataEngine.executeUpdate(dataAccess.conn, parsedSQL.getSQL(), modelRequest);
		}

		// 有BigTable，尝试定位目标表
		BigTable bigTable = this.getBigTable(parsedSQL.getTableName());
		if (bigTable == null) {
			throw new SQLException("Dest-table not found: " + strSQL);
		}
		// 获取连接
		dataAccess = this.selectConnection(hmDataGroup, dataService, strDefaultDataGroupId, parsedSQL.getTableName(), parsedSQL.getIdMath(), false, modelRequest, hmDataAccessUsed, trans);
		if (dataAccess == null) {// 没有拿到连接
			throw new SQLException("Cannot get connection: " + strSQL + "\r\n" + modelRequest.toXML());
		}

		// 拿到了连接
		this.selectTable(dataAccess, bigTable, parsedSQL.getIdMath(), false, modelRequest);

		// 修改SQL语句中的表名
		strSQL = parsedSQL.getSQL().toString().replaceAll("\\{T:" + parsedSQL.getTableName() + "\\}",
				parsedSQL.getTableName() + dataAccess.nTableIndex);

		// 执行数据库操作
		return dataAccess.dataEngine.executeUpdate(dataAccess.conn, strSQL, modelRequest);
	}

	/*
	 * 处理一个Block
	 * 
	 * @return 0-自然执行完毕，1-碰到Break退出，2-碰到Return退出
	 */
	private int handleBlock(
				HashMap<String, DataEngineList> hmDataGroup,  DataService dataService, HashMap<String, DataAccess> hmDataAccessUsed, 
				SQLTrans trans,  BlockType block,  Model modelRequest, Model modelResponse, Result ret
			) throws SQLException, IOException {
		
		String strDefaultDataGroupId = trans.getDataGroupId();
		int nItemCount = block.getBlockTypeItemCount();
		for (int i = 0; i < nItemCount; i++) {
			BlockTypeItem blockItem = block.getBlockTypeItem(i);
			if (blockItem.getInsert() != null) {// Insert
												// 获得将要执行的SQL
				Insert insert = (Insert) blockItem.getInsert();
				StringBuilder strbSQL = new StringBuilder();
				handleSQLBlock(insert, modelRequest, strbSQL);
				String strSQL = strbSQL.toString();
				// 执行SQL
				this.executeInsert(hmDataGroup, dataService, hmDataAccessUsed, trans, strSQL, modelRequest);
			} else if (blockItem.getUpdate() != null) {// Update
														// 获得将要执行的SQL
				Update update = (Update) blockItem.getUpdate();
				StringBuilder strbSQL = new StringBuilder();
				handleSQLBlock(update, modelRequest, strbSQL);
				String strSQL = strbSQL.toString();

				// 执行SQL
				int nRecordCount = this.executeUpdate(hmDataGroup, dataService, hmDataAccessUsed, trans, strSQL,
						modelRequest);
				String strRecordCountId = update.getRecordCountId();
				if (strRecordCountId.length() > 0) {// 输出受影响的记录数
					strRecordCountId = strRecordCountId.substring(1, strRecordCountId.length() - 1);
					modelRequest.set(strRecordCountId, nRecordCount);
				}
			} else if (blockItem.getDelete() != null) {// Delete
														// 获得将要执行的SQL
				Delete delete = (Delete) blockItem.getDelete();
				StringBuilder strbSQL = new StringBuilder();
				handleSQLBlock(delete, modelRequest, strbSQL);
				String strSQL = strbSQL.toString();

				// 执行SQL
				int nRecordCount = this.executeUpdate(hmDataGroup, dataService, hmDataAccessUsed, trans, strSQL,
						modelRequest);
				String strRecordCountId = delete.getRecordCountId();
				if (strRecordCountId.length() > 0) {// 输出受影响的记录数
					strRecordCountId = strRecordCountId.substring(1, strRecordCountId.length() - 1);
					modelRequest.set(strRecordCountId, nRecordCount);
				}
			} else if (blockItem.getSelectField() != null) {
				// 获得将要执行的SQL
				SelectField selectField = (SelectField) blockItem.getSelectField();
				StringBuilder strbSQL = new StringBuilder();
				handleSQLBlock(selectField, modelRequest, strbSQL);
				String strSQL = strbSQL.toString();

				// 执行SQL
				JObject objFieldValue = this.executeQueryFieldExt(hmDataGroup, dataService, hmDataAccessUsed, trans,strSQL, modelRequest, selectField.getDecryptFieldNames());
				if (objFieldValue == null) {
					continue;
				}
				DataType nType = objFieldValue.getType();
				Object objValue = objFieldValue.getValue();

				String strOutputId = selectField.getOutputId();
				strOutputId = strOutputId.substring(1, strOutputId.length() - 1);
				ValueUtils.setValueByDataType(modelRequest, strOutputId, nType, objValue);
			} else if (blockItem.getSelectRecord() != null) {
				// 获得将要执行的SQL
				SelectRecord selectRecord = (SelectRecord) blockItem.getSelectRecord();
				StringBuilder strbSQL = new StringBuilder();
				handleSQLBlock(selectRecord, modelRequest, strbSQL);
				String strSQL = strbSQL.toString();

				// 执行SQL
				Model modelRecord = new Model();
				int nRecordCount = this.executeQueryRecord(hmDataGroup, dataService, hmDataAccessUsed, trans, strSQL,modelRequest, modelRecord, selectRecord.getDecryptFieldNames());
				String strRecordCountId = selectRecord.getRecordCountId();
				if (strRecordCountId.length() > 0) {// 输出受影响的记录数
					strRecordCountId = strRecordCountId.substring(1, strRecordCountId.length() - 1);
					modelRequest.set(strRecordCountId, nRecordCount);
				}

				String strOutputId = selectRecord.getOutputId();
				strOutputId = strOutputId.substring(1, strOutputId.length() - 1);
				if (nRecordCount > 0) {
					modelRequest.set(strOutputId, modelRecord);
				}
			} else if (blockItem.getSelectRecordSet() != null) {// SelectRecordSet
																// 获得将要执行的SQL
				SelectRecordSet selectRecordSet = (SelectRecordSet) blockItem.getSelectRecordSet();
				StringBuilder strbSQL = new StringBuilder();
				handleSQLBlock(selectRecordSet, modelRequest, strbSQL);
				String strSQL = strbSQL.toString();

				// 执行SQL
				Models modelArrayField = new Models("");
				int nRecordCount = this.executeQueryRecordSet(hmDataGroup, dataService, hmDataAccessUsed, trans, strSQL, modelRequest, modelArrayField, selectRecordSet.getDecryptFieldNames());
				String strRecordCountId = selectRecordSet.getRecordCountId();
				if (strRecordCountId.length() > 0) {// 输出受影响的记录数
					strRecordCountId = strRecordCountId.substring(1, strRecordCountId.length() - 1);
					modelRequest.set(strRecordCountId, nRecordCount);
				}

				String strOutputId = selectRecordSet.getOutputId();
				strOutputId = strOutputId.substring(1, strOutputId.length() - 1);
				String strKeyFieldName = selectRecordSet.getKeyFieldName();
				if (strKeyFieldName.length() == 0) {// RecordSet输出到数组
					modelRequest.set(strOutputId, modelArrayField.getValue());
				} else {// RecordSet输出到HashMap
					Model[] modelsRecordSet = modelArrayField.getValue();
					Model modelRecordSet = new Model();
					for (int j = 0; j < modelsRecordSet.length; j++) {
						modelRecordSet.set(modelsRecordSet[j].getObject(strKeyFieldName).toString(), modelsRecordSet[j]);
					}
					modelRequest.set(strOutputId, modelRecordSet);
				}
			} else if (blockItem.getIf() != null) {
				int nResult = this.handleIf(hmDataGroup, dataService, hmDataAccessUsed, trans, (If) blockItem.getIf(), modelRequest, modelResponse, ret);
				if (nResult == 0) {// 自然执行完毕
					continue;
				} else {// 碰到Break或Return
					return nResult;
				}
			} else if (blockItem.getFor() != null) {
				int nResult = this.handleFor(hmDataGroup, dataService, hmDataAccessUsed, trans, (For) blockItem.getFor(), modelRequest, modelResponse, ret);
				if (nResult == 0) {// 自然执行完毕
					continue;
				} else {// 碰到Break或Return
					return nResult;
				}
			} else if (blockItem.getSetVar() != null) {
				SetVar sv = blockItem.getSetVar();
				ValueUtils.setVar(sv, modelRequest);
			} else if (blockItem.getSelectConnection() != null) {// SelectTable选择BigTable的单个表
				SelectConnection st = blockItem.getSelectConnection();

				String strIdFieldId = st.getIdFieldId();
				if (strIdFieldId.length() > 0) {
					strIdFieldId = strIdFieldId.substring(1, strIdFieldId.length() - 1);
				}
				this.selectConnection(hmDataGroup, dataService, strDefaultDataGroupId, st.getBigTableName(), strIdFieldId, true, modelRequest, hmDataAccessUsed, trans);
			} else if (blockItem.getReturn() != null) {
				com.gavin.schema.dataservice.Return returnObject = (com.gavin.schema.dataservice.Return) blockItem.getReturn();
				ValueUtils.handleReturn(returnObject, modelRequest, modelResponse, ret);

				return 2;
			} else if (blockItem.getHandleTrans() != null) {
				this.handleHandleTrans(hmDataGroup, dataService, hmDataAccessUsed, trans, blockItem.getHandleTrans(),modelRequest, modelResponse, ret);
				continue;
			} else if (blockItem.getBreak() != null) {// Break退出
				return 1;
			} else if (blockItem.getCommit() != null) {
				this.executeCommit(hmDataAccessUsed);
			} else if (blockItem.getRollback() != null) {
				this.executeRollback(hmDataAccessUsed);
			} else if (blockItem.getLog() != null) {
				Log log = blockItem.getLog();
				TransLog.handleLog(logger,log, modelRequest, modelResponse);
			}
		}

		return 0;
	}




	
	//------------------------------------------------------------------------------------------------------------------------------------------
	/**
	 * 执行commit语句
	 * 
	 * @throws Exception
	 */
	private void executeCommit(HashMap<String, DataAccess> hmDataAccessUsed) throws SQLException, IOException {
		// 提交事务
		Iterator<DataAccess> iterator = hmDataAccessUsed.values().iterator();
		while (iterator.hasNext()) {
			DataAccess dataAccess = iterator.next();
			if (dataAccess.conn.getAutoCommit() == false) {// 尚未提交
				dataAccess.conn.commit();
			}
		}
	}
	
	/**
	 * 批量commit
	 * @param hmDataAccessUsed
	 */
	private void commitTrans(HashMap<String, DataAccess> hmDataAccessUsed) {
		// 提交事务
		Iterator<Map.Entry<String, BigDataEngine.DataAccess>> iterator = hmDataAccessUsed.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry<String, BigDataEngine.DataAccess> entry = iterator.next();
			if (entry.getKey() == null) {
				continue;
			}
			DataAccess dataAccess = (DataAccess) entry.getValue();
			if (dataAccess == null) {
				continue;
			}
			try {
				if (dataAccess.conn.getAutoCommit() == false) {// 尚未提交
					dataAccess.conn.commit();
					// dataAccess.conn.setAutoCommit(true);
				}
			} catch (Exception e) {
			}
		}
	}

	/**
	 * 执行rollback语句
	 * @throws Exception
	 */
	private void executeRollback(HashMap<String, DataAccess> hmDataAccessUsed) throws SQLException, IOException {
		// 提交事务
		Iterator<DataAccess> iterator = hmDataAccessUsed.values().iterator();
		while (iterator.hasNext()) {
			DataAccess da = iterator.next();
			Connection conn = null;
			if (da != null) {
				conn = da.conn;
			}
			if (conn != null && conn.getAutoCommit() == false) {// 尚未提交
				conn.rollback();
			}
		}
	}
	/**
	 * 批量rollback
	 * @param hmDataAccessUsed
	 */
	private void rollbackTrans(HashMap<String, DataAccess> hmDataAccessUsed) {
		// 提交事务
		Iterator<Map.Entry<String, BigDataEngine.DataAccess>> iterator = hmDataAccessUsed.entrySet().iterator();
		while (iterator.hasNext()) {
			Map.Entry<String, BigDataEngine.DataAccess> entry = iterator.next();
			if (entry.getKey() == null) {
				continue;
			}
			DataAccess dataAccess = (DataAccess) entry.getValue();
			if (dataAccess == null) {
				continue;
			}
			try {
				if (dataAccess.conn.getAutoCommit() == false) {// 尚未提交
					dataAccess.conn.rollback();
				}
			} catch (Exception e) {
			}
		}
	}
	
	
//	public static void main(String[] args) throws Exception {
//		BigDataEngine engine = new BigDataEngine();
//
//		Model modelRequest = new Model();
//		modelRequest.set("lId", 99);
//		modelRequest.set("lAge", 2);
//		modelRequest.set("strLoginId", "Testasdasdf");
//
//		long lValue = engine.getKeyIdValue("strLoginId", modelRequest, 10000);
//		System.out.println(lValue);
//	}

}
